/* PvPSystem
 * Copyright (C) 2010 Spectre
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#ifndef PvPSystem_H
#define PvPSystem_H

#define MAX_PVP_RANKS 14
#define MAX_PVP_RANK_DIFF 3
#define PVP_EXP_MULTIPLIER 250
#define PVP_RANK_DIFF_COST 500
#define PVP_EXP_DIFF_COST 5

struct PvPSystemData;
struct PvPSystemRewardData;

enum TRANCE_SHOPS
{
	TRANCE_SHOP_NONE,
	TRANCE_SHOP_PVP,
	TRANCE_SHOP_TITLE,
	TRANCE_SHOP_MORPH,
	MAX_TRANCE_SHOPS,
};

enum PVP_REWARD_CURRENCY
{
	PVP_REWARD_NON_FFA		= 1500,
	PVP_REWARD_FFA			= 3500,
};

enum PVP_REWARD_EXP
{
	PVP_EXP_NON_FFA_KILL	= 15,
	PVP_EXP_FFA_KILL		= 25,
};

enum PVP_STATS
{
	PVP_STAT_RANK,
	PVP_STAT_TOTAL_KILLS,
	PVP_STAT_NON_FFA_KILLS,
	PVP_STAT_FFA_KILLS,
	PVP_STAT_TOTAL_DEATHS,
	PVP_STAT_TOTAL_EXP
};

enum ALLIANCE_PVP_TITLES
{
	ALLIANCE_TITLE_PRIVATE			= 1,
	ALLIANCE_TITLE_CORPORAL			= 2,
	ALLIANCE_TITLE_SERGEANT			= 3,
	ALLIANCE_TITLE_MASTER_SERGEANT	= 4,
	ALLIANCE_TITLE_SERGEANT_MAJOR	= 5,
	ALLIANCE_TITLE_KNIGHT			= 6,
	ALLIANCE_TITLE_KNIGHT_LT		= 7,
	ALLIANCE_TITLE_KNIGHT_CPT		= 8,
	ALLIANCE_TITLE_KNIGHT_CHAMP		= 9,
	ALLIANCE_TITLE_LT_COMMANDER		= 10,
	ALLIANCE_TITLE_COMMANDER		= 11,
	ALLIANCE_TITLE_MARSHAL			= 12,
	ALLIANCE_TITLE_FIELD_MARSHAL	= 13,
	ALLIANCE_TITLE_GRAND_MARSHAL	= 14,
};

enum HORDE_PVP_TITLES
{
	HORDE_TITLE_SCOUT			= 15,
	HORDE_TITLE_GRUNT			= 16,
	HORDE_TITLE_SERGEANT		= 17,
	HORDE_TITLE_SENIOR_SERGEANT	= 18,
	HORDE_TITLE_FIRST_SERGEANT	= 19,
	HORDE_TITLE_STONE_GUARD		= 20,
	HORDE_TITLE_BLOOD_GUARD		= 21,
	HORDE_TITLE_LEGIONNAIRE		= 22,
	HORDE_TITLE_CENTURION		= 23,
	HORDE_TITLE_CHAMPION		= 24,
	HORDE_TITLE_LT_GENERAL		= 25,
	HORDE_TITLE_GENERAL			= 26,
	HORDE_TITLE_WARLORD			= 27,
	HORDE_TITLE_HIGH_WARLORD	= 28,
};

// PvPManager
class PvPManager : public ScriptableObject
{
	typedef std::map<uint32, PvPSystemRewardData*> PvPRewardMap;
	public:
		PvPManager();
		~PvPManager();

		// Database Management
		void LoadFromDatabase();

		// Pvp Rewards
		PvPSystemRewardData *GetPvPRewardData(uint8 rankId);

		// Hooks
		void OnPlayerPvPKill(Player *pVictim, Player *pKiller);

	private:

		// PvP Rewards
		PvPRewardMap m_pvpRewards;
};

#define sPvPManager (*ACE_Singleton<PvPManager, ACE_Null_Mutex>::instance())

// PvPSystem
class PvPSystem
{
	public:
		typedef std::map<std::string, uint32> PvPTargetMap;
		PvPSystem(Player *pPlayer);
		~PvPSystem();

		// Database
		void LoadFromDatabase(Player *pPlayer);
		void SaveToDatabase();

		// Stats Management
		void ModifyStat(uint8 statIndex, uint32 statValue);
		uint32 GetStatValue(uint8 statIndex);
		uint32 GetNextRankExp();
		const char *GetRankName();

		// Rally Area
		void SetInRallyArea(bool inRally) { m_inRally = inRally; }
		bool IsInRallyArea() { return m_inRally; }
		float CalcDistance(WorldLocation aVect, WorldLocation bVect);

		// PvP Interaction
		void OnPvPKill(Player *pAttacker, Player *pVictim);
		uint32 GetTimeStamp();

		// Currency Management
		void ModifyCurrency(Player *pPlayer, int32 Amt, bool Remove);

		// Gossip System
		void SetLastVendorListId(uint32 listId) { m_lastVendorListId = listId; }
		uint32 GetLastVendorListId() { return m_lastVendorListId; }
		uint32 GetShopDiscount(uint8 shopId, uint32 itemPrice);
		uint8 GetShopAccessLevel(uint8 shopId) { return m_shopAccess[shopId]; }
		void DisplayPvPRewards();

	private:

		// Internal PvP Checks
		bool _isHonorable(Player *pAttacker, Player *pVictim);
		void _addTarget(std::string Ip, uint32 Time);
		uint32 _getLastKilledTime(std::string Ip);

		// Currency Management
		uint32 _getCurrencyIncrease(uint32 defaultCurrency);
		uint16 _getDivisorForAmt(uint32 Amt);
		std::string _getCurrencyName(uint32 Amt);

		// PvP Exp
		void _awardPvPRank(uint8 rankId);
		void _applyRankRewards(int8 rankId = -1);
		uint32 _getExpIncrease(uint32 defaultExp);


	protected:

		// PlayerData
		PvPSystemData *m_pvpData;
		Player *m_plr;


		// Rally Area
		bool m_inRally;

		// Internal PvP Data Storage
		PvPTargetMap m_pvpTargets;

		// PvPRewards
		uint32 m_lastVendorListId;
		float m_shopDiscount;
		float m_currencyIncrease;
		float m_expIncrease;
		uint8 m_shopAccess[MAX_TRANCE_SHOPS];
};

// Creature
class CreatureExtender
{
	public:
		CreatureExtender() { m_inRally = false; }
		~CreatureExtender() {}

		void SetInRally(bool inRally) { m_inRally = inRally; }
		bool IsInRally() { return m_inRally; }

	protected:
		bool m_inRally;
};

#endif // PvPSystem_H

